package com.profgj.profgj.config;

import com.profgj.profgj.filter.VerifyCodeFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.annotation.Resource;

/**
 * 安全访问限制配置类
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 认证失败处理对象
     */
    @Resource
    private MyAuthenticationFailureHandler myAuthenticationFailureHandler;
    /**
     *  验证码过滤器
     */
    @Resource
    private VerifyCodeFilter verifyCodeFilter;

    /**
     * 用户明细服务
     */
    @Resource
    private UserDetailsService userDetailsService;

    /**
     * 将配置文件中system.user.password.secret 中的值 注入到secret成员变量中
     */
    @Value("${system.user.password.secret}")
    private String secret = null;

    /**
     * 配置密码加密和认证服务
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        // 使用盐Pbkdf2密码加密器
        PasswordEncoder passwordEncoder = new Pbkdf2PasswordEncoder(this.secret);

        // 添加配置认证服务
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }


    /**
     * URI访问权限配置
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        // SpringSecurity添加验证码过滤器 verifyCodeFilter 过滤器
        http.addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class);

        // 解决iframe访问失败的问题
        http.headers().frameOptions().sameOrigin();
        // 授权的所有请求
        http.authorizeRequests()
                //匹配的路径                                                     //指定角色
                //注: 不管使用 hasAnyRole hasRole  hasAnyAuthority hasAuthority  数据库必须是 ROLE_ADMIN,ROLE_USER
                /**
                 * 首页
                 */
                .antMatchers("/","/index").hasAnyRole("ADMIN","USER")
                /**
                 * 请求处理的接口
                 */
                // 管理员和企业用户均可访问
                .antMatchers("/cas/**").hasAnyRole("ADMIN","USER")
                .antMatchers("/eny/**").hasAnyRole("ADMIN","USER")
                .antMatchers("/en/**").hasAnyRole("ADMIN","USER")
                .antMatchers("/project/**").hasAnyRole("ADMIN","USER")
                .antMatchers("/reqment/**").hasAnyRole("ADMIN","USER")
                .antMatchers("/publishfile/**").hasAnyRole("ADMIN","USER")
                .antMatchers("/usr/**").hasAnyRole("ADMIN","USER")
                // 只限管理员访问
                .antMatchers("/statis/**").hasAnyRole("ADMIN")
                .antMatchers("/uit/**").hasAnyRole("ADMIN")
                .antMatchers("/yeg/**").hasAnyRole("ADMIN")
                .antMatchers("/usrOp/**").hasAnyRole("ADMIN")
                /**
                 * 页面访问跳转请求权限分配 管理员和企业均可
                 */
                .antMatchers("/page/EnterpriseAdd").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/EnterpriseChange").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/EnterpriseInfo").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/jltj").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/ProductAdd").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/ProductChange").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/ProductInfo").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/ProjectAdd").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/ProjectChange").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/ProjectInfo").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/ProjectDocmentAdd").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/ProjectDocmentChange").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/ProjectDocmentInfo").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/UserChange2").hasAnyRole("USER")
                .antMatchers("/page/UserInfo").hasAnyRole("ADMIN","USER")
                .antMatchers("/page/PolicyFileInfo").hasAnyRole("ADMIN","USER")
                  //  其他都是只是管理员
                .antMatchers("/page/PolicyFileAdd").hasAnyRole("ADMIN")
                .antMatchers("/page/PolicyFileChange").hasAnyRole("ADMIN")
                .antMatchers("/page/Unit_Add").hasAnyRole("ADMIN")
                .antMatchers("/page/Unit_Change").hasAnyRole("ADMIN")
                .antMatchers("/page/Unit_Info").hasAnyRole("ADMIN")
                .antMatchers("/page/UserChange").hasAnyRole("ADMIN")
                .antMatchers("/page/UserAdd").hasAnyRole("ADMIN")
                .antMatchers("/page/UserLog").hasAnyRole("ADMIN")
                .antMatchers("/page/YEC_Info").hasAnyRole("ADMIN")

                //剩下所有请求无条件可以访问
                .anyRequest().permitAll().and()

                //对于没有配置的其他用户 允许匿名访问
                .anonymous()
                .and()
                //表单登入
                .formLogin()
                .failureHandler(myAuthenticationFailureHandler)
                // 登录页面
                .loginPage("/login")
                // 登录处理URL // 登录成功页面 // 失败页面
//                .loginProcessingUrl().defaultSuccessUrl().failureUrl()
                //登入成功后悔跳转到来路页面并不会跳转到指定的页面,当alwaysUse为true功能和successForwardUrl一样
                .defaultSuccessUrl("/index",true)
                //登入失败跳转到fail
                .failureUrl("/fail")
                .permitAll()
                .and()
                //登出成功跳转页面
                .logout().logoutSuccessUrl("/")
                .and()
                // 配置记住我并给一个过期时间
//                .rememberMe().tokenValiditySeconds()
                //http基础认证
                .httpBasic()
                .and() //token interceptor 根据header 生成认证信息
                //关闭CSRF跨站攻击防护 因为只有get可以访问 post put del 返回 403
                //如果想开启csrf的话需要在表单中添加 _csrf 计算出来的token的32位长度的加密字符串
                .csrf().disable();
    }

//    @Override
//    public void configure(WebSecurity web) throws Exception {
//        // 可以做忽略拦截请求
//        web.ignoring().antMatchers("/vercode");
//    }
}
